/*
Copyright 2010  Murali Devi (profdevi@gmail.com)

This file is part of ComineGL Project.

ComineGL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

ComineGL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with ComineGL.  If not, see <http://www.gnu.org/licenses/>.

This code uses the irrlicht and irrklang libraries.  Please read
the libraries copyrights at 

	irrlicht library:  http://irrlicht.sourceforge.net
	irrklang library:  http://www.ambiera.com/irrklang

*/



//v1.3 copyright Comine.com 20101211S21
#include "MStdLib.h"
#include "MIrrlicht.h"
#include "MCGLNodeInfo.h"
#include "MCGLTriangleSelectorInfo.h"


//******************************************************
//**  MCGLTriangleSelectorInfo class
//******************************************************
void MCGLTriangleSelectorInfo::ClearObject(void)
	{
	mSceneMgr=NULL;
	mSelector=NULL;
	}


////////////////////////////////////////////////
MCGLTriangleSelectorInfo::MCGLTriangleSelectorInfo(void)
	{  ClearObject();  }


////////////////////////////////////////////////
MCGLTriangleSelectorInfo::~MCGLTriangleSelectorInfo(void)
	{  Destroy();  }


////////////////////////////////////////////////
bool MCGLTriangleSelectorInfo::Create(ISceneManager *scenemgr)
	{
	Destroy();
	MStdAssert(scenemgr!=NULL);

	mSceneMgr=scenemgr;
	mSelector=mSceneMgr->createMetaTriangleSelector();
	if(mSelector==NULL)
		{
		Destroy();
		return false;
		}

	return true;
	}


////////////////////////////////////////////////
bool MCGLTriangleSelectorInfo::Destroy(void)
	{
	if(mSelector!=NULL)
		{
		mSelector->drop();
		mSelector=NULL;
		}

	ClearObject();
	return true;
	}


////////////////////////////////////////////////
IMetaTriangleSelector *MCGLTriangleSelectorInfo::GetSelector(void)
	{
	return mSelector;
	}


///////////////////////////////////////////////
bool MCGLTriangleSelectorInfo::Clear(void)
	{
	mSelector->removeAllTriangleSelectors();
	return true;
	}


///////////////////////////////////////////////
bool MCGLTriangleSelectorInfo::Add(MCGLNodeInfo *nodeinfo)
	{
	MStdAssert(nodeinfo!=NULL);

	ISceneNode *scenenode=nodeinfo->GetNode();
	ITriangleSelector *selector=NULL;

	MCGLNodeInfoType nodetype=nodeinfo->GetNodeType();
	switch(nodetype)
		{
		///////////////////////////////////////////
		case CGLNIT_BILLBOARD:
		case CGLNIT_CUBE:
			{
			selector=mSceneMgr->createTriangleSelectorFromBoundingBox(scenenode);
			if(selector==NULL)
				{
				return false;
				}

			break;
			}

		///////////////////////////////////////////
		case CGLNIT_ANIMATED_MESH:
			{
			selector=mSceneMgr->createTriangleSelectorFromBoundingBox(scenenode);
			if(selector==NULL)
				{
				return false;
				}		

			break;
			}

	
		////////////////////////////////////////////
		case CGLNIT_MESH:
			{
			IMeshSceneNode *imeshscenenode=(IMeshSceneNode*)scenenode;
			selector=mSceneMgr->createTriangleSelector(imeshscenenode->getMesh(),scenenode);
			if(selector==NULL)
				{
				return false;
				}

			break;
			}

		///////////////////////////////////////////
		case CGLNIT_TERRAIN:
			{
			ITerrainSceneNode *terrainscenenode=(ITerrainSceneNode*)scenenode;
			selector=mSceneMgr->createTerrainTriangleSelector(terrainscenenode);
			if(selector==NULL)
				{
				return false;
				}	

			break;	
			}

		//////////////////////////////////////////
		case CGLNIT_OCT_TREE:
			{
			IMeshSceneNode *imeshscenenode=(IMeshSceneNode *)scenenode;
			selector=mSceneMgr->createOctreeTriangleSelector(imeshscenenode->getMesh(),imeshscenenode);
			if(selector==NULL)
				{
				return false;
				}

			break;
			}

		///////////////////////////////////////////
		default:
			{
			// Worst case scenario, use bounded box
			selector=mSceneMgr->createTriangleSelectorFromBoundingBox(scenenode);
			if(selector==NULL)
				{
				return false;
				}

			return true;
			}
		}

	scenenode->setTriangleSelector(selector);

	//=We now have a selector
	mSelector->addTriangleSelector(selector);
	selector->drop();

	return true;
	}


